package com.kelp.codetoolkit.service.impl

import com.intellij.database.util.common.isNotNullOrEmpty
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.xml.XmlFile
import com.kelp.codetoolkit.cache.CollectionPsiClassCache
import com.kelp.codetoolkit.data.ControllerRequestData
import com.kelp.codetoolkit.data.RequestParamData
import com.kelp.codetoolkit.data.RequestParamDetailData
import com.kelp.codetoolkit.data.ResponseParamDetailData
import com.kelp.codetoolkit.enums.JavaCollectionEnum
import com.kelp.codetoolkit.enums.RequestMethodEnum
import com.kelp.codetoolkit.enums.ServerPackageEnum
import com.kelp.codetoolkit.enums.XMLSQLMethodTemplateEnum
import com.kelp.codetoolkit.respository.CodeToolkitGlobalSettingRepository
import com.kelp.codetoolkit.service.MethodHandleService
import com.kelp.codetoolkit.service.WriteFileService
import com.kelp.codetoolkit.ui.form.MethodParamsSettingDialog
import com.kelp.codetoolkit.utils.HandleFileUtil
import com.kelp.codetoolkit.utils.NameHandleUtil
import com.kelp.codetoolkit.utils.ProjectUtil
import com.kelp.codetoolkit.utils.frame.SpringUtil

/**
 * @author: liuyuebai
 * @date: 2025/1/13 15:35
 * @description:
 */
class MethodHandleServiceImpl: MethodHandleService {

    override fun handleService(project: Project, currentJavaFile: PsiJavaFile,methodContent: MethodParamsSettingDialog) {
        val psiClass = currentJavaFile.classes[0]?:return
        val className = psiClass.name?:return
        if (!ServerPackageEnum.isService(className)){
            return
        }
        val builder = StringBuilder()
        assembleComment(methodContent.getMethodComment(),builder)
        val importPsiClassList:MutableSet<PsiClass> = mutableSetOf()
        //----------------方法签名组装-------------------
        assembleServiceReturnParam(project,methodContent.getResponseParamData(),builder,importPsiClassList)
        builder.append(" ")
        builder.append(methodContent.getMethodName())
        assembleRequestParams(methodContent.getRequestParamsData(),builder,importPsiClassList)
        builder.append(";")
        //----------------方法签名组装-------------------
        commonWriteMethod(project,builder,psiClass)
        WriteFileService.getInstance(project).writeImportPackage(project, currentJavaFile,importPsiClassList)
    }

    override fun handleService(project: Project, methodContent: MethodParamsSettingDialog, selectJavaFile: PsiJavaFile, selectClassName:String, selectPackageEnum: ServerPackageEnum) {
        val servicePath = getFilePath(selectJavaFile, selectClassName, selectPackageEnum,ServerPackageEnum.SERVICE)
        val serviceJavaFile = HandleFileUtil.getPsiJavaFile(servicePath, project)?:return
        handleService(project,serviceJavaFile,methodContent)
    }

    override fun handleProviderToService(project: Project, methodContent: MethodParamsSettingDialog, selectJavaFile: PsiJavaFile, selectClassName: String, selectPackageEnum: ServerPackageEnum) {
        val servicePath = getProviderToPath(project,selectJavaFile,selectClassName,selectPackageEnum,ServerPackageEnum.SERVICE,methodContent.getModuleName())
        val serviceJavaFile = HandleFileUtil.getPsiJavaFile(servicePath, project)?:return
        handleService(project,serviceJavaFile,methodContent)
    }


    override fun handleJavaMapper(project: Project, currentJavaFile: PsiJavaFile,methodContent:MethodParamsSettingDialog){
        val psiClass = currentJavaFile.classes[0]
        val className = psiClass.name?:return
        if (!ServerPackageEnum.isJavaMapper(className)){
            return
        }
        val builder = StringBuilder()
        assembleComment(methodContent.getMethodComment(),builder)
        val importPsiClassList:MutableSet<PsiClass> = mutableSetOf()
        val cacheParam = CollectionPsiClassCache.getCache(project, "org.apache.ibatis.annotations.Param")
        if (null != cacheParam) {
            importPsiClassList.add(cacheParam)
        }
        //----------------方法签名组装-------------------
        assembleReturnParam(methodContent.getResponseParamData(),builder,importPsiClassList)
        builder.append(" ")
        builder.append(methodContent.getMethodName())
        assembleMapperRequestParams(project,methodContent.getRequestParamsData(),builder,importPsiClassList)
        builder.append(";")
        //----------------方法签名组装-------------------
        commonWriteMethod(project,builder,psiClass)
        WriteFileService.getInstance(project).writeImportPackage(project, currentJavaFile,importPsiClassList)
    }

    override fun handleJavaMapper(project: Project, methodContent: MethodParamsSettingDialog, selectJavaFile: PsiJavaFile, selectClassName: String, selectPackageEnum: ServerPackageEnum) {
        val javaMapperPath = getFilePath(selectJavaFile, selectClassName, selectPackageEnum,ServerPackageEnum.MAPPER_JAVA)
        val mapperJavaFile = HandleFileUtil.getPsiJavaFile(javaMapperPath, project)?:return
        handleJavaMapper(project,mapperJavaFile,methodContent)
    }

    override fun handleProviderToJavaMapper(project: Project, methodContent: MethodParamsSettingDialog, selectJavaFile: PsiJavaFile, selectClassName: String, selectPackageEnum: ServerPackageEnum) {
        val javaMapperPath = getProviderToPath(project,selectJavaFile,selectClassName,selectPackageEnum,ServerPackageEnum.MAPPER_JAVA,methodContent.getModuleName())
        val mapperJavaFile = HandleFileUtil.getPsiJavaFile(javaMapperPath, project)?:return
        handleJavaMapper(project,mapperJavaFile,methodContent)
    }

    override fun handleServiceImpl(project: Project, currentJavaFile: PsiJavaFile, methodContent: MethodParamsSettingDialog) {
        val psiClass = currentJavaFile.classes[0]
        val className = psiClass.name?:return
        if (!ServerPackageEnum.isServiceImpl(className)){
            return
        }
        val builder = StringBuilder()
        val importPsiClassList:MutableSet<PsiClass> = mutableSetOf()
        assembleOverride(builder)
        assembleAccess( builder)
        //----------------方法签名组装-------------------
        assembleServiceReturnParam(project,methodContent.getResponseParamData(),builder,importPsiClassList)
        builder.append(" ")
        builder.append(methodContent.getMethodName())
        assembleRequestParams(methodContent.getRequestParamsData(),builder,importPsiClassList)
        //----------------方法签名组装-------------------
        builder.append("{")
        assembleNewLine(builder)
        assembleNewLine(builder)
        builder.append("}")
        commonWriteMethod(project,builder,psiClass)
        WriteFileService.getInstance(project).writeImportPackage(project, currentJavaFile,importPsiClassList)
    }

    override fun handleServiceImpl(project: Project, methodContent: MethodParamsSettingDialog, selectJavaFile: PsiJavaFile, selectClassName: String, selectPackageEnum: ServerPackageEnum) {
        val serviceImplPath = getFilePath(selectJavaFile, selectClassName, selectPackageEnum,ServerPackageEnum.SERVICE_IMPL)
        val serviceImplFile = HandleFileUtil.getPsiJavaFile(serviceImplPath, project)?:return
        handleServiceImpl(project,serviceImplFile,methodContent)
    }

    override fun handleProviderToServiceImpl(project: Project, methodContent: MethodParamsSettingDialog, selectJavaFile: PsiJavaFile, selectClassName: String, selectPackageEnum: ServerPackageEnum) {
        val serviceImplPath = getProviderToPath(project,selectJavaFile,selectClassName,selectPackageEnum,ServerPackageEnum.SERVICE_IMPL,methodContent.getModuleName())
        val serviceImplFile = HandleFileUtil.getPsiJavaFile(serviceImplPath, project)?:return
        handleServiceImpl(project,serviceImplFile,methodContent)
    }

    override fun handleProviderImpl(project: Project, currentJavaFile: PsiJavaFile, methodContent: MethodParamsSettingDialog) {
        val psiClass = currentJavaFile.classes[0]?:return
        val className = psiClass.name?:return
        if (!ServerPackageEnum.isProviderImpl(className)){
            return
        }
        val builder = StringBuilder()
        val importPsiClassList:MutableSet<PsiClass> = mutableSetOf()
        assembleOverride(builder)
        assembleAccess( builder)
        //----------------方法签名组装-------------------
        assembleViewResponse(project,methodContent.getResponseParamData(),builder,importPsiClassList)
        builder.append(" ")
        builder.append(methodContent.getMethodName())
        assembleRequestParams(methodContent.getRequestParamsData(),builder,importPsiClassList)
        //----------------方法签名组装-------------------
        builder.append("{")
        assembleNewLine(builder)
        assembleNewLine(builder)
        builder.append("}")
        commonWriteMethod(project,builder,psiClass)
        WriteFileService.getInstance(project).writeImportPackage(project, currentJavaFile,importPsiClassList)
    }

    override fun handleProviderImpl(project: Project, methodContent: MethodParamsSettingDialog, selectJavaFile: PsiJavaFile, selectClassName: String, selectPackageEnum: ServerPackageEnum) {
        val providerImplPath = getFilePath(selectJavaFile, selectClassName, selectPackageEnum,ServerPackageEnum.PROVIDER_IMPL)
        val providerJavaFile = HandleFileUtil.getPsiJavaFile(providerImplPath, project)?:return
        handleProviderImpl(project,providerJavaFile,methodContent)
    }

    override fun handleProviderToProviderImpl(project: Project, methodContent: MethodParamsSettingDialog, selectJavaFile: PsiJavaFile, selectClassName: String, selectPackageEnum: ServerPackageEnum) {
        val providerImplPath = getProviderToPath(project,selectJavaFile,selectClassName,selectPackageEnum,ServerPackageEnum.PROVIDER_IMPL,methodContent.getModuleName())
        val providerJavaFile = HandleFileUtil.getPsiJavaFile(providerImplPath, project)?:return
        handleProviderImpl(project,providerJavaFile,methodContent)
    }

    override fun handleProvider(project: Project, currentJavaFile: PsiJavaFile, methodContent: MethodParamsSettingDialog) {
        val psiClass = currentJavaFile.classes[0]
        val className = psiClass.name?:return
        if (!ServerPackageEnum.isProvider(className)){
            return
        }
        val builder = StringBuilder()
        assembleComment(methodContent.getMethodComment(),builder)
        val importPsiClassList:MutableSet<PsiClass> = mutableSetOf()
        //----------------方法签名组装-------------------
        assembleViewResponse(project,methodContent.getResponseParamData(),builder,importPsiClassList)
        builder.append(" ")
        builder.append(methodContent.getMethodName())
        assembleRequestParams(methodContent.getRequestParamsData(),builder,importPsiClassList)
        builder.append(";")
        //----------------方法签名组装-------------------
        commonWriteMethod(project,builder,psiClass)
        WriteFileService.getInstance(project).writeImportPackage(project, currentJavaFile,importPsiClassList)
    }

    override fun handleProvider(project: Project, methodContent: MethodParamsSettingDialog, selectJavaFile: PsiJavaFile, selectClassName: String, selectPackageEnum: ServerPackageEnum) {
        val selectModule = ProjectUtil.getModule(selectJavaFile)
        val selectModuleName = selectModule?.name?:""
        val settingState = CodeToolkitGlobalSettingRepository.getInstance(project).state
        val stubModuleName = settingState.getStubModuleName()
        if (selectModuleName.isBlank()){
            return
        }
        if (selectModuleName.isNotNullOrEmpty) {
            var providerPath = getFilePath(selectJavaFile, selectClassName, selectPackageEnum, ServerPackageEnum.PROVIDER).replace(selectModuleName,stubModuleName)
            val pathArr = providerPath.split("/")
            var stubPackage = stubModuleName.replace("-","")
            if (settingState.getStubPackage().isNotNullOrEmpty){
                stubPackage = settingState.getStubPackage()
            }
            providerPath = providerPath.replace(pathArr[pathArr.size - 3],stubPackage)
            val providerJavaFile = HandleFileUtil.getPsiJavaFile(providerPath, project)?:return
            handleProvider(project,providerJavaFile,methodContent)
        }
    }

    override fun handleController(project: Project, currentJavaFile: PsiJavaFile, methodContent: MethodParamsSettingDialog) {
        val psiClass = currentJavaFile.classes[0]
        val className = psiClass.name?:return
        if (!ServerPackageEnum.isController(className)){
            return
        }
        val builder = StringBuilder()
        assembleComment(methodContent.getMethodComment(),builder)
        val importPsiClassList:MutableSet<PsiClass> = mutableSetOf()
        assembleControllerRequest(builder,methodContent.getControllerRequest(),methodContent.getMethodName())
        assembleAccess(builder)
        //----------------方法签名组装-------------------
        assembleViewResponse(project,methodContent.getResponseParamData(),builder,importPsiClassList)
        builder.append(" ")
        builder.append(methodContent.getMethodName())
        assembleRequestParams(methodContent.getRequestParamsData(),builder,importPsiClassList)
        builder.append("{")
        assembleNewLine(builder)
        assembleNewLine(builder)
        builder.append("}")
        //----------------方法签名组装-------------------
        commonWriteMethod(project,builder,psiClass)
        WriteFileService.getInstance(project).writeImportPackage(project, currentJavaFile,importPsiClassList)
    }

    override fun handleController(project: Project, methodContent: MethodParamsSettingDialog, selectJavaFile: PsiJavaFile, selectClassName: String, selectPackageEnum: ServerPackageEnum) {
        val controllerPath = getFilePath(selectJavaFile, selectClassName, selectPackageEnum,ServerPackageEnum.CONTROLLER)
        val controllerJavaFile = HandleFileUtil.getPsiJavaFile(controllerPath, project)?:return
        handleController(project,controllerJavaFile,methodContent)
    }

    override fun handleMapperXml(project: Project, psiJavaFile: PsiJavaFile, methodContent: MethodParamsSettingDialog, fileName: String) {
        val module = ProjectUtil.getModule(psiJavaFile)?:return
        commonHandleMapperXml(module,project, psiJavaFile, methodContent, fileName)
    }

    override fun handleProviderToMapperXml(project: Project, psiJavaFile: PsiJavaFile, methodContent: MethodParamsSettingDialog, fileName: String) {
        val serviceModule = ProjectUtil.getModule(project, methodContent.getModuleName())
        commonHandleMapperXml(serviceModule,project, psiJavaFile, methodContent, fileName)
    }

    private fun commonHandleMapperXml(module: Module?, project: Project, psiJavaFile: PsiJavaFile, methodContent: MethodParamsSettingDialog, fileName: String){
        module?:return
        val xmlMethod = methodContent.getXmlMethod()
        if (xmlMethod.isBlank()){
            return
        }
        val resourcesPath = SpringUtil.getResourcesPath(module)?:return
        var xmlPath = resourcesPath + "/mapper/" + fileName + "Mapper.xml"
        var psiFile = HandleFileUtil.getPsiFile(xmlPath, project)
        if (psiFile == null){
            val parentName = psiJavaFile.parent?.name
            xmlPath = resourcesPath + "/mapper/"+parentName + fileName + "Mapper.xml"
            psiFile = HandleFileUtil.getPsiFile(xmlPath, project)
        }
        psiFile?:return
        if (psiFile is XmlFile){
            val rootTag = psiFile.rootTag?:return
            val builder = StringBuilder()
            // 添加新行和缩进
            builder.append("\n    ")
            builder.append("<").append(xmlMethod).append(" ").append("id=\"").append(methodContent.getMethodName()).append("\" ")
            if(XMLSQLMethodTemplateEnum.isSelect(xmlMethod))  {
              builder.append("resultType=\"").append(methodContent.getResponseParamData().returnParamClass?.qualifiedName)
            }
            builder.append("\">")
            assembleNewLine(builder)
            assembleNewLine(builder)
            builder.append("    </").append(methodContent.getXmlMethod()).append(">")
            // 获取Document对象并插入内容
            val document = psiFile.viewProvider.document?: return
            // 查找 </mapper> 标签位置
            var mapperEndOffset: Int? = null
            val childrenTags = rootTag.children // 假设可以获取子标签列表，实际按 XML 解析库 API 为准
            for (tag in childrenTags.reversed()) {
                if (tag.text.contains(methodContent.getXmlMethod())) {
                    mapperEndOffset = tag.textRange.endOffset
                    break
                }
            }
            if (null == mapperEndOffset){
                for (tag in childrenTags.reversed()) {
                    if (tag.text.contains("select")) {
                        mapperEndOffset = tag.textRange.endOffset-8
                        assembleNewLine(builder)
                        break
                    }
                    if (tag.text.contains("update")) {
                        mapperEndOffset = tag.textRange.endOffset-8
                        assembleNewLine(builder)
                        break
                    }
                    if (tag.text.contains("delete")) {
                        mapperEndOffset = tag.textRange.endOffset-8
                        assembleNewLine(builder)
                        break
                    }
                    if (tag.text.contains("mapper")) {
                        mapperEndOffset = tag.textRange.endOffset-8
                        assembleNewLine(builder)
                        break
                    }
                }
            }
            mapperEndOffset?:return
            WriteCommandAction.runWriteCommandAction(project) {
                document.insertString(mapperEndOffset, builder.toString())
            }
        }
    }

    private fun getProviderToPath(project: Project,selectJavaFile:PsiJavaFile,selectClassName:String,selectFilePackageEnum: ServerPackageEnum,toFilePackageEnum: ServerPackageEnum,moduleName:String): String{
        var filePath = getFilePath(selectJavaFile, selectClassName, selectFilePackageEnum,toFilePackageEnum)
        val selectModule = ProjectUtil.getModule(selectJavaFile)
        if (selectModule != null) {
            filePath = filePath.replace(selectModule.name,moduleName)
            val module = ProjectUtil.getModule(project, moduleName)
            if (module != null) {
                val applicationFile = SpringUtil.getModuleApplicationFile(module)
                if (applicationFile != null && applicationFile is PsiJavaFile) {
                    var selectName =  selectJavaFile.classes[0].qualifiedName?:""
                    val indexOf = selectName.indexOf("." + selectFilePackageEnum.packageName)
                    selectName = selectName.substring(0,indexOf)
                    var serviceName =  applicationFile.classes[0].qualifiedName?:""
                    val serviceNameArr = serviceName.split(".")
                    val serviceIndexOf = serviceName.indexOf("." + serviceNameArr[serviceNameArr.size - 1])
                    serviceName = serviceName.substring(0, serviceIndexOf)
                    selectName = selectName.replace(".","/")
                    serviceName = serviceName.replace(".","/")
                    filePath = filePath.replace(selectName,serviceName)
                }
            }
        }
        return filePath
    }

    private fun getFilePath(selectJavaFile: PsiJavaFile,selectClassName:String,selectFilePackageEnum: ServerPackageEnum,toFilePackageEnum: ServerPackageEnum): String {
        val currentPath = selectJavaFile.virtualFile.path
        return currentPath.replace("/"+selectFilePackageEnum.packageName, "/"+toFilePackageEnum.packageName)
            .replace(selectJavaFile.name,selectClassName+toFilePackageEnum.suffix+".java")
    }

    private fun assembleReturnParam(responseParam: ResponseParamDetailData, builder: StringBuilder, importPsiClassList:MutableSet<PsiClass>){
        var shortClassName = responseParam.returnParamShortName
        if (shortClassName.isBlank()){
            shortClassName = "void"
        }
        handleLeftPointing(responseParam.collectionName,builder)
        handleMapKey(responseParam.collectionName,responseParam.mapKey,builder)
        builder.append(shortClassName)
        handleRightPointing(responseParam.collectionName,builder)
        builder.append(" ")
        addImportPsiClass(responseParam.returnParamClass,importPsiClassList)
        addImportPsiClass(responseParam.collectionParamPsiClass,importPsiClassList)
    }

    private fun assembleViewResponse(project: Project,responseParam:ResponseParamDetailData,builder: StringBuilder,importPsiClassList:MutableSet<PsiClass>){
        var shortClassName = responseParam.shortClassName
        if (shortClassName.isBlank()){
            shortClassName = "Void"
        }
        commonAssembleResponse(shortClassName,responseParam.paramClass,project,responseParam,builder,importPsiClassList)
    }

    private fun assembleServiceReturnParam(project: Project,responseParam:ResponseParamDetailData,builder: StringBuilder,importPsiClassList:MutableSet<PsiClass>){
        var shortClassName = responseParam.returnParamShortName
        if (shortClassName.isBlank()){
            shortClassName = "void"
        }
        commonAssembleResponse(shortClassName,responseParam.returnParamClass,project,responseParam,builder,importPsiClassList)
    }

    private fun commonAssembleResponse(shortClassName:String,importClass:PsiClass?,project: Project,responseParam:ResponseParamDetailData,builder: StringBuilder,importPsiClassList:MutableSet<PsiClass>) {
        val globalSettingState = CodeToolkitGlobalSettingRepository.getInstance(project).state
        val viewResponse = globalSettingState.getViewResponseSetting()
        if ("void" != shortClassName &&viewResponse.isNotNullOrEmpty){
            val arr = viewResponse.split(".")
            builder.append(arr[arr.size-1]).append("<")
            // 获取全局作用域
            val scope = GlobalSearchScope.allScope(project)
            val findClass = JavaPsiFacade.getInstance(project).findClass(viewResponse, scope)
            addImportPsiClass(findClass,importPsiClassList)
        }
        handleLeftPointing(responseParam.collectionName,builder)
        handleMapKey(responseParam.collectionName,responseParam.mapKey,builder)
        builder.append(shortClassName)
        handleRightPointing(responseParam.collectionName,builder)
        if (shortClassName.isNotNullOrEmpty){
            handleRightPointing(viewResponse,builder)
        }
        builder.append(" ")
        addImportPsiClass(importClass,importPsiClassList)
        addImportPsiClass(responseParam.collectionParamPsiClass,importPsiClassList)
    }


    private fun assembleRequestParams(requestParams: RequestParamData, builder: StringBuilder, importPsiClassList:MutableSet<PsiClass>){
        builder.append("(")
        val requestParamOne = requestParams.requestParamOne
        assembleServiceRequestParams(requestParamOne, builder, importPsiClassList)
        val requestParamTwo = requestParams.requestParamTwo
        handleMultipleRequestComma(requestParamTwo,builder)
        assembleServiceRequestParams(requestParamTwo,builder,importPsiClassList)
        val requestParamThree = requestParams.requestParamThree
        handleMultipleRequestComma(requestParamThree,builder)
        assembleServiceRequestParams(requestParamThree,builder,importPsiClassList)
        builder.append(")")
    }

    private fun assembleServiceRequestParams(requestParamDetail: RequestParamDetailData?, builder: StringBuilder, importPsiClassList:MutableSet<PsiClass>){
        requestParamDetail?:return
        val shortClassName = requestParamDetail.shortClassName
        if (shortClassName.isBlank()){
            return
        }
        var requestParamName = requestParamDetail.requestParamName
        if (requestParamName.isBlank()){
            requestParamName = NameHandleUtil.initialLowerCase(shortClassName)
        }
        commonHandleRequest(requestParamDetail,builder,importPsiClassList,requestParamName)
    }


    private fun assembleMapperRequestParams(project: Project,requestParams:RequestParamData,builder: StringBuilder,importPsiClassList:MutableSet<PsiClass>){
        builder.append("(")
        val requestParamOne = requestParams.requestParamOne
        assembleMapperRequestParams(project,requestParamOne,builder,importPsiClassList)
        val requestParamTwo = requestParams.requestParamTwo
        handleMultipleRequestComma(requestParamTwo,builder)
        assembleMapperRequestParams(project,requestParamTwo,builder,importPsiClassList)
        val requestParamThree = requestParams.requestParamThree
        handleMultipleRequestComma(requestParamThree,builder)
        assembleMapperRequestParams(project,requestParamThree,builder,importPsiClassList)
        builder.append(")")
    }

    private fun assembleMapperRequestParams(project: Project,requestParamDetail:RequestParamDetailData?,builder: StringBuilder,importPsiClassList:MutableSet<PsiClass>){
        requestParamDetail?:return
        val shortClassName = requestParamDetail.shortClassName
        if (shortClassName.isBlank()){
            return
        }
        var requestParamName = requestParamDetail.requestParamName
        if (requestParamName.isBlank()){
            requestParamName = NameHandleUtil.initialLowerCase(shortClassName)
        }
        builder.append("@Param(\"").append(requestParamName).append("\")")
        builder.append(" ")
        CollectionPsiClassCache.getCache(project,"org.apache.ibatis.annotations.Param")
        commonHandleRequest(requestParamDetail,builder,importPsiClassList,requestParamName)
    }

    private fun commonHandleRequest(requestParamDetail:RequestParamDetailData,builder: StringBuilder,importPsiClassList:MutableSet<PsiClass>,requestParamName:String){
        handleLeftPointing(requestParamDetail.collectionName,builder)
        handleMapKey(requestParamDetail.collectionName,requestParamDetail.mapKey,builder)
        builder.append(requestParamDetail.shortClassName)
        handleRightPointing(requestParamDetail.collectionName,builder)
        builder.append(" ")
        builder.append(requestParamName)
        addImportPsiClass(requestParamDetail.paramClass,importPsiClassList)
        addImportPsiClass(requestParamDetail.collectionParamPsiClass,importPsiClassList)
    }

    /**
     * 处理泛型 右尖括号
     */
    private fun handleLeftPointing(wrapperName:String?,builder: StringBuilder){
        if (wrapperName.isNotNullOrEmpty){
            builder.append(wrapperName)
            builder.append("<")
        }
    }

    /**
     * 处理泛型 右尖括号
     */
    private fun handleRightPointing(wrapperName:String?,builder: StringBuilder){
        if (wrapperName.isNotNullOrEmpty){
            builder.append(">")
        }
    }

    private fun handleMapKey(mapName:String,mapKey:String,builder: StringBuilder){
        if (JavaCollectionEnum.isMap(mapName)) {
            builder.append(mapKey).append(",")
        }
    }

    /**
     * 写入换行
     */
    private fun assembleNewLine(builder: StringBuilder) {
        val osName = System.getProperty("os.name")
//        if (osName.contains("Windows")) {
//            builder.append("\r\n")
//        }

//        if (osName.contains("Linux")) {
//            builder.append("\n")
//        }

        builder.append("\n")
    }

    /**
     * 导入包添加入集合
     */
    private fun addImportPsiClass(importPsiClass: PsiClass?,importPsiClassList:MutableSet<PsiClass>){
        importPsiClass?:return
        importPsiClassList.add(importPsiClass)
    }

    /**
     * 写入注释
     */
    private fun assembleComment(comment:String,builder: StringBuilder){
        builder.append("/** ")
        assembleNewLine(builder)
        builder.append(" * ").append(comment)
        assembleNewLine(builder)
        builder.append(" */")
        assembleNewLine(builder)
    }

    /**
     * 多个参数时，需要添加逗号
     */
    private fun handleMultipleRequestComma(requestParams: RequestParamDetailData?,builder: StringBuilder){
        if (null != requestParams && requestParams.shortClassName.isNotNullOrEmpty){
            builder.append(",")
        }
    }

    private fun assembleOverride(builder: StringBuilder){
        builder.append("@Override")
        assembleNewLine(builder)
    }

    private fun assembleControllerRequest(builder: StringBuilder,controllerRequestData: ControllerRequestData,methodName:String){
        val requestMethodEnum = RequestMethodEnum.get(controllerRequestData.requestMethod)
        var requestPath = controllerRequestData.requestPath
        if (requestPath.isBlank()){
            requestPath = methodName
        }
        builder.append(requestMethodEnum.springMethodName).append("(\"").append(requestPath).append("\")")
        assembleNewLine(builder)
    }

    private fun assembleAccess( builder: StringBuilder){
        builder.append("public").append(" ")
    }
    private fun commonWriteMethod(project: Project,methodContent:StringBuilder,psiClass:PsiClass){
        val createMethodFromText = JavaPsiFacade.getInstance(project).elementFactory.createMethodFromText(methodContent.toString(), psiClass)
        WriteCommandAction.runWriteCommandAction(project){
            try {
                psiClass.add(createMethodFromText)
            }catch (e:Exception){
                println(e.message)
            }
        }
    }
}